package com.panopset.nls;

import static com.panopset.Util.*;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import com.panopset.Util;
import com.panopset.gui.container.PanTextField;
import com.panopset.gui.container.Validator;
import java.util.logging.Level;
import java.util.logging.Logger;

public class LanguageNames {

    public static LanguageNames singleton;
    private Map<String, Map<String,String>> names;
    private static final String NAMES_PATH_TRG = PANSOPSET_USER_DIR + PATH_SEP + "nlsNames";
    private static final String NAMES_PATH_SRC = "/com/panopset/nls/names";
    private PanTextField baseLocaleTF;

    public static LanguageNames asLanguageNames() {
        if (singleton == null) {
            singleton = new LanguageNames();
        }
        return singleton;
    }


    private LanguageNames() {}

    public PanTextField getBaseLocaleTF() {
        if (baseLocaleTF == null) {
            String defaultValue = "en";
            String isoLang = Locale.getDefault().getISO3Language();
            if (isoLang != null && isoLang.length() > 1) {
                isoLang = isoLang.substring(0,2);
                String msg = validator.validate(isoLang);
                if (isPopulated(msg)) {
                    dspmsg(msg);
                } else {
                    defaultValue = isoLang;
                }
            } else {
                dspmsg(x("Current language not found") + COMMA + SINGLE_SPACE + x("using English")
                        + " (en)");
            }
            baseLocaleTF = new PanTextField(2, x("Base"), x("Base language"), defaultValue);
            baseLocaleTF.addValidator(validator);
        }
        return baseLocaleTF;
    }

    public String getBaseLocale() {
        return getBaseLocaleTF().getValue();
    }

    public void setBaseLocale(String nlsCode) {
        getBaseLocaleTF().setValue(nlsCode);
    }

    public String getName(String localeName) {
        return getName(getBaseLocale(), localeName);
    }
    /**
     * Get the name of a language, in a particular language.
     * @param localLocaleName
     * @param localeName
     * @return
     */
    public String getName(String localLocaleName, String localName) {
        Map<String,String> localNames = getNames().get(localLocaleName);
        if (localNames == null) {
            dspmsg(x("No translations found for " + localLocaleName));
            return EMPTY_STRING;
        } else {
            String rtn = localNames.get(localName);
            if (rtn == null) {
                dspmsg(x("Language ") + localName + x(" not found for ") + localLocaleName);
                return EMPTY_STRING;
            } else {
                return rtn;
            }
        }
    }

    /**
     *
     * @return Map of locale codes to language names.
     */
    public Map<String, Map<String,String>> getNames() {
        if (names == null) {
            names = new HashMap<String, Map<String,String>>();
            for (String localeName : FlagIcons.asFlagIcons().spritePackage.getResourceList()) {
                String fileName = FORWARD_SLASH + localeName + ".properties";
                try {
                    Util.copyLibraryResource(NAMES_PATH_SRC + fileName, NAMES_PATH_TRG + fileName);
                } catch (IOException ex) {
                    log(x("from") + ": " + NAMES_PATH_SRC + fileName);
                    log(x("to") + ": " + NAMES_PATH_TRG + fileName);
                    Logger.getLogger(LanguageNames.class.getName()).log(Level.SEVERE, null, ex);
                }
                names.put(localeName,
                        loadPropsFromFile(new File(NAMES_PATH_TRG + FORWARD_SLASH + fileName)));
            }
        }
        return names;
    }


    private final Validator validator = new Validator() {

        @Override
        public String validate(String value) {
            if (FlagIcons.asFlagIcons().spritePackage.getResourceList().contains(value)) {
                return "";
            } else {
                return x("No FlagIcon exists for language code")
                                + SINGLE_SPACE + value + SINGLE_SPACE
                                + x("using English")
                                + " (en)";
            }
        }

    };

}
